home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Lib / parse / ad_parse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  10.0 KB  |  500 lines

  1. /* ad_parse.c: parse an address */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Lib/parse/RCS/ad_parse.c,v 6.0 1991/12/18 20:23:41 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Lib/parse/RCS/ad_parse.c,v 6.0 1991/12/18 20:23:41 jpo Rel $
  9.  *
  10.  * $Log: ad_parse.c,v $
  11.  * Revision 6.0  1991/12/18  20:23:41  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16. #include "head.h"
  17. #include "adr.h"
  18. #include <varargs.h>
  19.  
  20. static void ad_copy_addresses(), 
  21.     ad_copy_errors();
  22.  
  23. static int rfc822thenx40090, x400thenrfc822(), parselose_exception();
  24.  
  25. int ad_fullparse (ad, rp, order_pref)
  26. register ADDR    *ad;
  27. RP_Buf        *rp;
  28. int        order_pref;
  29. {
  30.     ad->aparse->full = OK;
  31.     ad->aparse->dmnorder = order_pref;
  32.     
  33.     return ad_parse_aux (ad, rp);
  34. }
  35.  
  36. int ad_parse (ad, rp, order_pref)
  37. register ADDR    *ad;
  38. RP_Buf        *rp;
  39. int        order_pref;
  40. {
  41.     ad->aparse->full = NOTOK;
  42.     ad->aparse->dmnorder = order_pref;
  43.  
  44.     return ad_parse_aux (ad, rp);
  45. }
  46.  
  47. /*   */
  48.  
  49. int    ad_parse_aux (ad, rp)
  50. register ADDR    *ad;
  51. RP_Buf        *rp;
  52. {
  53.     int    is822, retval;
  54.     PP_DBG(("ad_parse ('%s', '%d')",
  55.         ad->ad_value,
  56.         ad->ad_type));
  57.  
  58.     or_myinit();
  59.  
  60.     switch (ad->ad_type) {
  61.         case AD_X400_TYPE:
  62.         return x400thenrfc822 (ad, rp);
  63.         case AD_822_TYPE:
  64.         return rfc822thenx400 (ad, rp);
  65.         default:
  66.  
  67.         /* guess */
  68.         /* shouldn't ever be call */
  69.         is822 = TRUE;
  70.         if (index(ad->ad_value, '/') != NULLCP)
  71.             is822 = FALSE;
  72.         if (index(ad->ad_value, '@') != NULLCP)
  73.             is822 = TRUE;
  74.         
  75.         if (is822 == TRUE) {
  76.             if (rp_isbad(retval =
  77.                      rfc822thenx400(ad, rp))) {
  78.                 /* may have guessed wrong */
  79.                 if (ad->ad_r400adr) {
  80.                     free(ad->ad_r400adr);
  81.                     ad->ad_r400adr = NULLCP;
  82.                 }
  83.  
  84.                 if (ad->ad_r822adr) {
  85.                     free (ad->ad_r822adr);
  86.                     ad->ad_r822adr = NULLCP;
  87.                 }
  88.                 if (ad->ad_parse_message) {
  89.                     free(ad->ad_parse_message);
  90.                     ad->ad_parse_message = NULLCP;
  91.                 }
  92.  
  93.                 return x400thenrfc822(ad, rp);
  94.             }
  95.         } else {
  96.             if (rp_isbad(retval = 
  97.                      x400thenrfc822(ad, rp))) {
  98.                 /* wrong guess */
  99.                 if (ad->ad_r400adr) {
  100.                     free(ad->ad_r400adr);
  101.                     ad->ad_r400adr = NULLCP;
  102.                 }
  103.  
  104.                 if (ad->ad_r822adr) {
  105.                     free (ad->ad_r822adr);
  106.                     ad->ad_r822adr = NULLCP;
  107.                 }
  108.                 if (ad->ad_parse_message) {
  109.                     free(ad->ad_parse_message);
  110.                     ad->ad_parse_message = NULLCP;
  111.                 }
  112.                 return rfc822thenx400(ad, rp);
  113.             }
  114.         }
  115.         return retval;
  116.     }
  117. }
  118.  
  119. /*   */
  120. extern char    or_error[];
  121. #define MAX_LOOP    10
  122.  
  123. static int rfc822thenx400 (ad, rp)
  124. register ADDR    *ad;
  125. RP_Buf        *rp;
  126. {
  127.     int    retval, cont, count;
  128.     char    *prev822adr, logerr[BUFSIZ];
  129.  
  130.     PP_DBG (("rfc822thenx400 ('%s', '%d')",
  131.          ad->ad_value, ad->ad_type));
  132.  
  133.     cont = TRUE;
  134.     count = 0;
  135.     /* parse 822 */
  136.     if (rp_isbad (retval =
  137.               rfc822_parse (ad))) {
  138.         ad_copy_errors(ad, logerr, TRUE);
  139.         return parselose_exception (rp,
  140.                         retval,
  141.                         logerr,
  142.                         ad->ad_parse_message);
  143.     }
  144.     do {
  145.         /* validate 822 */
  146.         ad->aparse->ad_type = AD_822_TYPE;
  147.         retval = rfc822_validate(ad, rp);
  148.  
  149.         /* convert 822 to x400 */
  150.         or_error[0] = '\0';
  151.         if (rp_isbad(rfc822_x400 (ad))) {
  152.             if (ad->ad_parse_message == NULLCP) 
  153.                 ad_copy_errors (ad, logerr, FALSE);
  154.             ad_copy_addresses (ad, FALSE);
  155.             return parselose_exception(rp,
  156.                            retval,
  157.                            logerr,
  158.                            ad->ad_parse_message);
  159.         }
  160.  
  161.         if (!rp_isbad(retval)) {
  162.             /* 822 is okay */
  163.             ad_copy_addresses (ad, TRUE);
  164.             return (ad->ad_parse_stat = RP_AOK);
  165.         }
  166.  
  167.         /* validate x400 */
  168.         or_error[0] = '\0';
  169.         ad->aparse->ad_type = AD_X400_TYPE;
  170.         retval = x400_validate(ad, rp);
  171.  
  172.         /* save first forms of address in main adr struct */
  173.         if (ad->ad_r822adr == NULLCP
  174.             || ad->ad_r400adr == NULLCP)
  175.             ad_copy_addresses(ad, FALSE);
  176.  
  177.         /* save first error messages in main adr struct */
  178.         if (ad->ad_parse_message == NULLCP)
  179.             ad_copy_errors(ad, logerr, FALSE);
  180.         
  181.  
  182.         /* reconvert back to 822 and see if different */
  183.         if (isstr(ad->aparse->r822_str))
  184.             prev822adr = strdup(ad->aparse->r822_str);
  185.         else
  186.             prev822adr = NULLCP;
  187.         
  188.         if (rp_isbad(x400_rfc822(ad))
  189.             || !isstr(ad->aparse->r822_str)
  190.             || prev822adr == NULLCP
  191.             || lexequ(ad->aparse->r822_str, prev822adr) == 0
  192.             || lexequ(ad->aparse->r822_str, ad->ad_value) == 0)
  193.             cont = FALSE;
  194.         else 
  195.             count++;
  196.         if (prev822adr) free(prev822adr);
  197.  
  198.         if (!rp_isbad(retval)) {
  199.             /* x400 is okay */
  200.             ad_copy_addresses(ad, TRUE);
  201.             return (ad->ad_parse_stat = RP_AOK);
  202.         }
  203.  
  204.     } while (count < MAX_LOOP && cont == TRUE);
  205.  
  206.     ad->aparse->ad_type = AD_822_TYPE;
  207.     return parselose_exception(rp,
  208.                    retval,
  209.                    logerr,
  210.                    ad->ad_parse_message);
  211. }
  212.  
  213. /*   */
  214.  
  215. static int x400thenrfc822 (ad, rp)
  216. register ADDR    *ad;
  217. RP_Buf        *rp;
  218. {
  219.     int    retval, cont, count;
  220.     char    *prevx400adr, logerr[BUFSIZ];
  221.     
  222.     cont = TRUE;
  223.     count = 0;
  224.  
  225.     PP_DBG (("x400thenrfc822 ('%s', '%d')",
  226.          ad->ad_value, ad->ad_type));
  227.     
  228.     /* parse x400 */
  229.     or_error[0] = '\0';
  230.     if (rp_isbad(retval = x400_parse(ad))) {
  231.         ad_copy_errors(ad, logerr, TRUE);
  232.         return parselose_exception (rp,
  233.                         retval,
  234.                         logerr,
  235.                         ad->ad_parse_message);
  236.     }
  237.     do {
  238.  
  239.         /* validate x400 */
  240.         or_error[0] = '\0';
  241.         ad->aparse->ad_type = AD_X400_TYPE;
  242.         retval = x400_validate(ad, rp);
  243.  
  244.         /* convert x400 to rfc */
  245.         
  246.         if (rp_isbad(x400_rfc822 (ad))) {
  247.             if (ad->ad_parse_message == NULLCP)
  248.                 ad_copy_errors(ad, logerr, FALSE);
  249.             ad_copy_addresses(ad, FALSE);
  250.             return parselose_exception(rp,
  251.                            retval,
  252.                            logerr,
  253.                            ad->ad_parse_message);
  254.         }
  255.  
  256.         if (!rp_isbad(retval)) {
  257.             /* x400 is okay */
  258.             ad_copy_addresses(ad, TRUE);
  259.             return (ad->ad_parse_stat = RP_AOK);
  260.         }
  261.         
  262.         /* validate 822 */
  263.         ad->aparse->ad_type = AD_822_TYPE;
  264.         retval = rfc822_validate(ad, rp);
  265.         
  266.         /* save first form of address in main adr struct */
  267.         if (ad->ad_r822adr == NULLCP
  268.             || ad->ad_r400adr == NULLCP)
  269.             ad_copy_addresses(ad, FALSE);
  270.         
  271.         /* save first form of address in main adr struct */
  272.         if (ad->ad_parse_message == NULLCP)
  273.             ad_copy_errors(ad, logerr, FALSE);
  274.         
  275.         /* reconvert back to x400 and see if different */
  276.         if (isstr(ad->aparse->x400_str))
  277.             prevx400adr = strdup(ad->aparse->x400_str);
  278.         else
  279.             prevx400adr = NULLCP;
  280.         
  281.         or_error[0] = '\0';
  282.         if (rp_isbad (rfc822_x400 (ad))
  283.             || !isstr(ad->aparse->x400_str)
  284.             || prevx400adr == NULLCP
  285.             || lexequ (ad->aparse->x400_str, prevx400adr) == 0
  286.             || lexequ (ad->aparse->x400_str, ad->ad_value) == 0)
  287.             cont = FALSE;
  288.         else
  289.             /* lets go round again */
  290.             count++;
  291.             
  292.         if (prevx400adr)
  293.             free(prevx400adr);
  294.  
  295.         if (!rp_isbad(retval)) {
  296.             /* 822 is okay */
  297.             ad_copy_addresses(ad, TRUE);
  298.             return (ad->ad_parse_stat = RP_AOK);
  299.         }
  300.     } while (count < MAX_LOOP && cont == TRUE);
  301.  
  302.     ad->aparse->ad_type = AD_X400_TYPE;
  303.  
  304.     return parselose_exception(rp,
  305.                    retval,
  306.                    logerr,
  307.                    ad->ad_parse_message);
  308. }
  309.  
  310. /*   */
  311.  
  312. /* copy addresses from ad->aparse to ad->ad_r*adr */
  313. /* overwriting depending on setting of force */
  314.  
  315. static void ad_copy_r822_address(ad, force)
  316. register ADDR    *ad;
  317. int        force;
  318. {
  319.     if (!ad->aparse->r822_str)
  320.         return;
  321.     if (ad->ad_r822adr) {
  322.         if (force != TRUE)
  323.             return;
  324.         free(ad->ad_r822adr);
  325.     }
  326.     ad->ad_r822adr = strdup(ad->aparse->r822_str);
  327. }
  328.  
  329. static void ad_copy_x400_address(ad, force)
  330. register ADDR    *ad;
  331. int        force;
  332. {
  333.     if (!ad->aparse->x400_str)
  334.         return;
  335.     if (ad->ad_r400adr) {
  336.         if (force != TRUE)
  337.             return;
  338.         free(ad->ad_r400adr);
  339.     }
  340.     ad->ad_r400adr = strdup(ad->aparse->x400_str);
  341. }
  342.  
  343. static void ad_copy_addresses(ad, force)
  344. register ADDR    *ad;
  345. int        force;
  346. {
  347.     ad_copy_r822_address(ad, force);
  348.     ad_copy_x400_address(ad, force);
  349. }
  350.  
  351. /* concat errors from ad->aparse to ad->ad_parse_message */
  352. /* overwriting depending on setting of force */
  353.  
  354. static void ad_copy_errors(ad, old, force)
  355. register ADDR    *ad;
  356. char    *old;
  357. int    force;
  358. {
  359.     char    *str;
  360.     if (ad->aparse->x400_error == NULLCP
  361.         && ad->aparse->r822_error == NULLCP)
  362.         return;
  363.  
  364.     if (ad->ad_type == AD_X400_TYPE) {
  365.         if (ad->aparse->x400_error)
  366.             str = ad->aparse->x400_error;
  367.         else 
  368.             str = ad->aparse->r822_error;
  369.     } else {
  370.         if (ad->aparse->r822_error)
  371.             str = ad->aparse->r822_error;
  372.         else
  373.             str = ad->aparse->x400_error;
  374.     }
  375.  
  376.     if (ad->ad_parse_message) {
  377.         if (force != TRUE)
  378.             return;
  379.         if (str)
  380.             free(ad->ad_parse_message);
  381.     }
  382.     
  383.     ad->ad_parse_message = strdup(str);
  384.  
  385.     if (old == NULLCP) 
  386.         return;
  387.  
  388.     if (ad->aparse->r822_error
  389.         && ad->aparse->x400_error) {
  390.         /* both errors */
  391.         if (lexequ(ad->aparse->x400_error,
  392.                ad->aparse->r822_error) == 0) {
  393.             (void) sprintf(old, "%s", ad->aparse->r822_error);
  394.             return;
  395.         }
  396.         
  397.         if (ad->ad_type == AD_X400_TYPE) 
  398.             (void) sprintf(old,
  399.                        "%s (%s)",
  400.                        ad->aparse->x400_error,
  401.                        ad->aparse->r822_error);
  402.         else
  403.             (void) sprintf(old,
  404.                        "%s (%s)",
  405.                        ad->aparse->r822_error,
  406.                        ad->aparse->x400_error);
  407.         return;
  408.     }
  409.  
  410.     if (ad->aparse->r822_error) 
  411.         (void) sprintf(old, "%s", ad->aparse->r822_error);
  412.     else if (ad->aparse->x400_error)
  413.         (void) sprintf(old, "%s", ad->aparse->x400_error);
  414. }
  415.  
  416. /*   */
  417.  
  418. set_error (ad, buf)
  419. register ADDR    *ad;
  420. char        *buf;
  421. {
  422.     char    **perr;
  423.     if (ad->aparse->ad_type == AD_X400_TYPE) 
  424.         perr = &(ad->aparse->x400_error);
  425.     else
  426.         perr = &(ad->aparse->r822_error);
  427.     
  428.     if (*perr)
  429.         free(*perr);
  430.     
  431.     *perr = strdup(buf);
  432. }
  433.  
  434. /*   */
  435.  
  436. static int parselose_exception (rp, val, logstr, str)
  437. RP_Buf  *rp;
  438. int     val;
  439. char    *logstr;
  440. char    *str;
  441. {
  442.     int    minlen;
  443.  
  444.     PP_LOG (LLOG_EXCEPTIONS, 
  445.         ("parselose (%s, '%s')", rp_valstr (val), logstr));
  446.  
  447.     rp -> rp_val = val;
  448.     
  449.     if (isstr(str)) {
  450.         minlen = (strlen(str) < sizeof (rp -> rp_line) - 1) ?
  451.             strlen(str) : sizeof (rp -> rp_line) - 1;
  452.         (void) strncpy (rp -> rp_line,  str, minlen);
  453.         rp -> rp_line[minlen] = '\0';
  454.     } else
  455.         (void) strcpy (rp -> rp_line,
  456.                    "ERROR");
  457.                     
  458.  
  459.     return val;
  460. }
  461.  
  462.     
  463. #ifdef lint
  464. /* VARARGS3 */
  465. int parselose (rp, val, str)
  466. RP_Buf  *rp;
  467. int     val;
  468. char    *str;
  469. {
  470.     return parselose (rp, val, str);
  471. }
  472. #else
  473. int parselose (va_alist)
  474. va_dcl
  475. {
  476.     va_list ap;
  477.     RP_Buf  *rp;
  478.     int     val;
  479.     char    buf[BUFSIZ];
  480.  
  481.     va_start (ap);
  482.  
  483.     rp = va_arg (ap, RP_Buf *);
  484.     val = va_arg (ap, int);
  485.  
  486.     _asprintf (buf, NULLCP, ap);
  487.  
  488.     PP_LOG (LLOG_TRACE, 
  489.         ("parselose (%s, '%s')", rp_valstr (val), buf));
  490.  
  491.     rp -> rp_val = val;
  492.     (void) strncpy (rp -> rp_line, buf, sizeof (rp -> rp_line) - 1);
  493.  
  494.     va_end (ap);
  495.  
  496.     return val;
  497. }
  498. #endif
  499.  
  500.